package com.seleniti.enpareja.web.desktop.server.model.integration.service.impl.appengine;

import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.List;

import org.ioc.commons.utils.jdo.JdoQueryHelper;
import org.ioc.commons.utils.logs.Log4JFormatterLogger;

import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.seleniti.enpareja.controller.common.domain.LoggedUserInfo;
import com.seleniti.enpareja.controller.model.integration.database.domain.User;
import com.seleniti.enpareja.web.desktop.server.common.util.CryptoUtils;

public class GAESecurityManagementService extends GAEService {
	/**
	 * Logger for this class
	 */
	private static final Log4JFormatterLogger logger = Log4JFormatterLogger
			.getLogger(GAESecurityManagementService.class);

	public GAESecurityManagementService() {
		logger.info("GAE Security management service instance");
	}

	public LoggedUserInfo tryLogin(String userEmail, String password) throws NoSuchAlgorithmException {

		LoggedUserInfo lui = new LoggedUserInfo();
		this.setSessionLoggedUserInfo(lui);

		JdoQueryHelper qhLogin = JdoQueryHelper.newQuery(pm,
				com.seleniti.enpareja.controller.model.integration.database.domain.User.class);

		String encryptedPassword = CryptoUtils.encrypt(password);

		qhLogin.andParams("userEmail==%s", userEmail);
		qhLogin.andParams("password==%s", encryptedPassword);
		@SuppressWarnings("unchecked")
		List<com.seleniti.enpareja.controller.model.integration.database.domain.User> found = (List<com.seleniti.enpareja.controller.model.integration.database.domain.User>) qhLogin
				.execute();
		com.seleniti.enpareja.controller.model.integration.database.domain.User epUser = (found != null && !found
				.isEmpty()) ? found.get(0) : null;

		if (epUser != null) {
			fillLoggedUserInfo(epUser, lui);
			lui.setRequiredExternalLogoutUrl(false);
		} else {
			JdoQueryHelper qhUserExists = JdoQueryHelper.newQuery(pm,
					com.seleniti.enpareja.controller.model.integration.database.domain.User.class);
			qhUserExists.andParams("userEmail==%s", userEmail);
			@SuppressWarnings("unchecked")
			List<com.seleniti.enpareja.controller.model.integration.database.domain.User> exists = (List<com.seleniti.enpareja.controller.model.integration.database.domain.User>) qhUserExists
					.execute();
			com.seleniti.enpareja.controller.model.integration.database.domain.User userExists = (exists != null && !exists
					.isEmpty()) ? exists.get(0) : null;

			if (userExists != null) {
//				lui.setUserEmail(userEmail);
//				lui.setPasswordSet(userExists.getPassword() != null && !userExists.getPassword().isEmpty());
				fillLoggedUserInfo(userExists, lui);
			}
		}

		return lui;

	}

	public void logout() {
		logger.info("Login out internally");
		this.setSessionLoggedUserInfo(null);
	}

	public String getGoogleLoginExternalUrl(String requestBackUrl) {
		UserService userService = UserServiceFactory.getUserService();

		String externalUrl = userService.createLoginURL(requestBackUrl);

		logger.info("External login url: " + externalUrl);

		return externalUrl;
	}

	public String getGoogleLogoutExternalUrl(String requestBackUrl) {
		logger.info("Login out externally");
		logout();

		UserService userService = UserServiceFactory.getUserService();
		String logoutUrl = userService.createLogoutURL(requestBackUrl);

		logger.info("External logout url: " + logoutUrl);

		return logoutUrl;
	}

	public boolean isApplicationRunningOnline() {
		/**
		 * Web implementation. Assuming deployed online.
		 */
		return true;
	}

	public void updateLastAccess(String userId) {
		User user = pm.getObjectById(User.class, userId);
		user.setLastAccess(new Date());
	}
}
